home *** CD-ROM | disk | FTP | other *** search
- /* SCHEME.CB
- ************************************************************************
- * *
- * PC Scheme/Geneva 4.00 CBrief code *
- * *
- * (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- * (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- * *
- *----------------------------------------------------------------------*
- * *
- * Brief Support *
- * *
- *----------------------------------------------------------------------*
- * *
- * Created by: Larry Bartholdi Date: 1992 *
- * Revision history: *
- * - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- * *
- * ``In nomine omnipotentii dei'' *
- ************************************************************************/
-
- #include <dialog.h>
-
- #define SIMPLEINDENT 2 // in (dummy
- // ..(xxx))
- #define COMPLETENAME (inq_environment("BSCHEME")+"SCHEME.CMP")
- #define TRANSITNAME (inq_environment("BSCHEME")+"SCHEME.TMP")
- #define MINMENU 15
- #define MAXMENU 30
- #define COMMENTPOS 49
-
- int s_completion;
- int s_mode;
- string s_tokens;
-
- /************************************************************************
- * Initialise the scheme package *
- ************************************************************************/
- void .s()
- {
- string whoami;
-
- keyboard_push();
- assign_to_key("<Enter>","s_enter");
- assign_to_key("<Ctrl-h>", "s_help");
- assign_to_key(")","s_paren");
- assign_to_key(";","s_semi");
- assign_to_key("<Tab>","s_tab");
- assign_to_key("<Shift-Tab>","s_comment");
- assign_to_key("<Ctrl-G>","s_list_proc");
- assign_to_key("<Ctrl-A>","s_mark_near");
- assign_to_key("<Ctrl-Z>","s_mark_far");
- assign_to_key("<Alt-F10>","s_eval_all");
- assign_to_key("<Ctrl-F10>","s_eval_mark");
- assign_to_key("<Ctrl-Left>","s_prev");
- assign_to_key("<Ctrl-Right>","s_next");
- assign_to_key("<Ctrl-F1>","s_toggle");
-
- use_local_keyboard(inq_keyboard());
- keyboard_pop(1);
-
- tabs( 9, 17 );
-
- // neat bug in CBRIEF: the system would crash
- // were this written as 's_tokens = ".." + "..";'
- s_tokens = " ";
- s_tokens = s_tokens + "DEFINE DEFINE-INTEGRABLE SET! LAMBDA NAMED-LAMBDA REC ";
- s_tokens = s_tokens + "LET LETREC LET* FLUID-LET ";
- s_tokens = s_tokens + "MACRO CALL/CC CASE WHEN APPLY-IF ";
- s_tokens = s_tokens + "WITH-INPUT-FROM-FILE CALL-WITH-INPUT-FILE AUTOLOAD-FROM-FILE ";
- s_tokens = s_tokens + "WITH-OUTPUT-TO-FILE CALL-WITH-OUTPUT-FILE ";
- // these always get indented by SIMPLEINDENT
- inq_names( whoami );
- message("File: %s [PCS package]", whoami );
- }
-
- void .sw()
- {
- global int s_use_sw;
-
- if( first_time() )
- s_use_sw = inq_macro(".sw");
- if( s_use_sw )
- .s();
- }
-
- void _init(...)
- {
- .s();
- s_completion = create_buffer("*completion*", COMPLETENAME, 1 );
- s_mode = 1;
- del( TRANSITNAME );
- }
-
- /* Define a mouse event handler to exit from the process if a mouse
- ** event occurs. Save the parameters to pass on to the current handler
- ** after the process exits.
- */
-
- int s_recurse; // Flag to tell _invalid_key we're active.
- void s_idlemouse();
-
- int s_mousevent,
- s_parm1,
- s_parm2,
- s_parm3,
- s_parm4;
-
- /*
- ** s_wait:
- **
- ** This routine accepts the return code from the search routines and
- ** does marking based on that return code. It can be replaced by the
- ** user to modify the marking action.
- */
-
- void s_wait( int match_length, int countidle, string wait )
- {
- if (!inq_kbd_char ())
- {
- drop_anchor ();
- next_char (match_length - 1 - (match_length != 1));
- swap_anchor ();
- keyboard_push ();
-
- s_recurse++;
-
- set_mouse_action( "s_idlemouse" );
- s_mousevent = 0;
-
- if( countidle )
- register_macro (4, "s_wait_idle");
- execute_macro( wait );
- if( countidle )
- unregister_macro (4, "s_wait_idle");
- s_recurse--;
-
- keyboard_pop ();
- raise_anchor ();
-
- if (s_mousevent)
- {
- string mse_handler;
- sprintf(mse_handler, "%s %d %d %d %d", inq_mouse_action(), s_parm1, s_parm2, s_parm3, s_parm4);
- execute_macro(mse_handler);
- }
- }
- }
-
- /* This function is called if a mouse event occurs while a pattern is
- ** marked after a search.
- */
-
- void s_idlemouse(int p1, int p2, int p3, int p4)
- {
- s_parm1 = p1;
- s_parm2 = p2;
- s_parm3 = p3;
- s_parm4 = p4;
- s_mousevent = 1;
- exit();
- }
-
- void s_wait_idle ()
- {
- if (inq_idle_time ())
- exit ();
- }
-
- /*
- ** _invalid_key:
- **
- ** This routine is called when an "invalid" key is pressed during normal
- ** macro processing. If the s_recurse variable isn't set, we just
- ** call down to the default _invalid_key handler. Otherwise, we exit the
- ** shell process we're in, and allow the keystroke to be processed again.
- */
-
- void _invalid_key (void)
- {
- if (s_recurse)
- exit ();
- else
- _invalid_key ();
- }
-
- int s_matchback()
- {
- int count;
-
- while( count >= 0 )
- {
- if( !prev_char() )
- return FALSE;
- if( !prev_char( 1 + (read(1) == "\\") ) ||
- search_back("[~\\\\]|{\\\\\\\\}[()\"\\|]") <= 0 )
- {
- if( search_back("[()\"\\|]") <= 0 )
- return FALSE;
- if( prev_char() ) /* beginning ? */
- return TRUE;
- }
- else next_char( 1 + (read(1) == "\\") );
-
- switch( read(1) )
- {
- case "(":
- count--;
- case ")":
- count++;
- case "\"":
- if( !prev_char(2) )
- return FALSE;
- if( search_back("[~\\\\]\"") <= 0 )
- return FALSE;
- right();
- case "|":
- if( !prev_char(2) )
- return FALSE;
- if( search_back("[~\\\\]\\|") <= 0 )
- return FALSE;
- right();
- }
- }
- return TRUE;
- }
-
- int s_matchfwd()
- {
- int count;
-
- while( count >= 0 )
- {
- if( search_fwd("[~\\\\][()\"\\|]") <= 0 )
- return FALSE;
- next_char();
-
- switch( read(1) )
- {
- case "(":
- count++;
- case ")":
- count--;
- case "\"":
- {
- int len;
- if( (len = search_fwd("\"\"|{*[~\\\\]\"}")) <= 0 )
- return FALSE;
- next_char( len-2 );
- }
- case "|":
- {
- int len;
- if( (len = search_fwd("\\|\\||{*[~\\\\]\\|}")) <= 0 )
- return FALSE;
- next_char( len-2 );
- }
- }
- }
- return TRUE;
- }
-
- /************************************************************************
- * indent the current line/the marked block *
- ************************************************************************/
- void s_indent_line()
- {
- string line;
- int curline, curcol = 1;
-
- move_abs( NULL, 1 );
- line = read();
- line = ltrim( substr( line, 1, strlen(line)-1 ) );
- delete_to_eol();
- save_position();
-
- if( s_matchback() )
- {
- string buf = trim( read() );
-
- inq_position( NULL, curcol );
-
- if( substr(line,1,1) == ";")
- curcol = 1; /* never indent comments */
- else
- if( substr(line,1,1) != ")")
- {
- int i;
-
- if( search_string("(*[( \t]", buf, i ) )
- {
- if( index( s_tokens, " "+upper(substr(buf,2,i-2))+" ") )
- curcol += SIMPLEINDENT;
- else {
- int j;
-
- if( search_string("(*[( \t]+[~ \t]", buf, j ) )
- i = j - 1;
- curcol += i - (substr(buf,i,1) == "(");
- }
- }
- else curcol += SIMPLEINDENT;
- }
- }
- restore_position();
- move_abs( NULL, curcol );
- insert( line );
- move_abs( NULL, curcol );
- }
-
- void s_indent()
- {
- if( inq_marked() )
- {
- int start, startline, end;
- inq_marked( start, startline, end, NULL );
- if( startline > 1 )
- start++;
- save_position();
- while( start <= end )
- {
- move_abs( start++, 1 );
- s_indent_line();
- }
- restore_position();
- }
- else s_indent_line();
- }
-
- /************************************************************************
- * close a parenthesis, highlighting the matched ( *
- ************************************************************************/
- void s_parenwait()
- {
- refresh();
- process();
- }
-
- void s_paren()
- {
- int firstline, line, matchline, col;
-
- insert(")");
- {
- string l;
- save_position();
- move_abs( NULL, 1 );
- l = read();
- restore_position();
- l = trim( ltrim( substr( l, 1, strlen(l)-1 ) ) );
- if( l == ")")
- {
- s_indent_line();
- right();
- }
- }
-
- inq_position( line, col );
- top_of_window();
- inq_position( firstline );
- move_abs( line, col );
-
- left();
- if( !s_matchback() )
- {
- beep();
- error("No match.");
- move_abs( line, col );
- return;
- }
- inq_position( matchline );
- if( matchline < firstline )
- {
- string matchtext;
- matchtext = read();
- message( "Line %d: %s", matchline, substr( matchtext, 1, strlen(matchtext) - 1 ) );
- } else s_wait( 1, 1, "s_parenwait");
-
- move_abs( line, col );
- }
-
- /************************************************************************
- * Suppress indentation for comments *
- ************************************************************************/
- void s_semi()
- {
- insert(";");
- {
- string l;
- save_position();
- move_abs( NULL, 1 );
- l = read();
- restore_position();
- l = trim( ltrim( substr( l, 1, strlen(l)-1 ) ) );
- if( l == ";")
- {
- move_abs( NULL, 1 );
- delete_to_eol();
- insert(";");
- }
- }
- }
-
- /************************************************************************
- * complete the current word *
- ************************************************************************/
- string s_wordstart;
-
- void s_cycletab()
- {
- int buf;
- string new;
-
- if( inq_marked() )
- delete_block();
- else raise_anchor();
- drop_anchor(4);
-
- buf = set_buffer( s_completion );
- if( !search_fwd(" "+s_wordstart, 0, 0 ) )
- {
- message("No more completion.");
- move_abs( 1, 1 );
- new = "";
- } else {
- new = read();
- new = substr( new, strlen(s_wordstart)+2, strlen(new)-strlen(s_wordstart)-2 );
- move_rel( 1 );
- }
- set_buffer( buf );
- insert( new );
- }
-
- void s_aborttab()
- {
- if( inq_marked() )
- delete_block();
- else raise_anchor();
- drop_anchor(4);
-
- exit();
- }
-
- void s_tabwait()
- {
- int end, start, buf;
-
- raise_anchor(); // forget what's been done by s_wait()
- assign_to_key("<Tab>", "s_cycletab");
- assign_to_key("<Esc>", "s_aborttab");
-
- save_position();
- inq_position( NULL, end );
- left();
- search_back("[( \t\n]");
- next_char();
- inq_position( NULL, start );
- if( end > start )
- s_wordstart = read( end - start );
- else s_wordstart = "";
- restore_position();
-
- buf = set_buffer( s_completion );
- move_abs( 1, 1 );
- set_buffer( buf );
-
- s_cycletab();
- refresh();
- process();
- }
-
- void s_tab()
- {
- int col;
-
- if( !s_mode )
- {
- insert("\t");
- return;
- }
- inq_position( NULL, col );
- if( col == 1 || inq_marked() )
- s_indent();
- else {
- string prev;
- prev_char();
- prev = read(1);
- next_char();
- if( search_string("[ \n\t()\"']", prev ) )
- {
- int tillend = strlen( ltrim(read()) );
- /* remember last locus */
- move_abs( NULL, 1 );
- s_indent();
- inq_position( NULL, col );
- {
- int newcol;
- end_of_line();
- inq_position( NULL, newcol );
- if( newcol < col )
- move_abs( NULL, col );
- }
- if( tillend > 0 )
- move_rel( NULL, 1-tillend );
- } else s_wait( 1, 0, "s_tabwait");
- }
- }
-
- /************************************************************************
- * enter a newline, indent the next line *
- ************************************************************************/
- void s_enter()
- {
- insert("\n");
- if( s_mode )
- s_indent_line();
- }
-
- /************************************************************************
- * tabulate to put a comment *
- ************************************************************************/
- void s_comment()
- {
- int col;
-
- end_of_line();
- inq_position( NULL, col );
- if( col < COMMENTPOS )
- while( col < COMMENTPOS )
- {
- insert("\t");
- inq_position( NULL, col );
- }
- else insert(" ");
- insert("; ");
- }
-
- /************************************************************************
- * Initialise marking process *
- ************************************************************************/
- int s_mark_start()
- {
- save_position();
- while( inq_marked() )
- raise_anchor();
-
- if( read(1) != ")")
- if( !s_matchfwd() )
- {
- error("No match forward.");
- restore_position();
- return FALSE;
- }
- mark();
- restore_position();
- save_position();
- if( read(1) != "(")
- if( !s_matchback() )
- {
- error("No match backward.");
- restore_position();
- return FALSE;
- }
- restore_position(0);
- return TRUE;
- }
-
- /************************************************************************
- * Extend a mark *
- ************************************************************************/
- int s_mark_further()
- {
- swap_anchor();
- save_position();
- if( !s_matchfwd() )
- {
- restore_position();
- swap_anchor();
- return FALSE;
- }
- swap_anchor();
- save_position();
- if( !s_matchback() )
- {
- restore_position();
- swap_anchor();
- restore_position();
- swap_anchor();
- return FALSE;
- }
- restore_position(0);
- restore_position(0);
- return TRUE;
- }
-
- /************************************************************************
- * Mark near parentheses, or extend current mark *
- ************************************************************************/
- void s_mark_near()
- {
- if( inq_marked() )
- s_mark_further();
- else s_mark_start();
- }
-
- /************************************************************************
- * Mark far parentheses *
- ************************************************************************/
- int s_mark_far()
- {
- if( !s_mark_start() )
- return FALSE;
-
- // now the current position is at the start of the small
- // list matched, the anchor at the end. Try to extend the list.
-
- while( s_mark_further() );
- return TRUE;
- }
-
- /************************************************************************
- * Evaluate the mark (or the current s-expr) in PCS *
- ************************************************************************/
- void s_eval_mark()
- {
- int tmp = create_buffer("*transit*", TRANSITNAME, 0 ), buf;
- string name;
-
- inq_names( name );
-
- if( !inq_marked() )
- if( !s_mark_far() )
- return;
- copy();
- buf = set_buffer( tmp );
- paste();
- write_buffer();
- set_buffer( buf );
- delete_buffer( tmp );
- exit();
- }
-
- /************************************************************************
- * Evaluate the buffer (in PCS) *
- ************************************************************************/
- void s_eval_all()
- {
- int tmp = create_buffer("*transit*", TRANSITNAME, 0 ), buf;
- string name;
-
- inq_names( name );
-
- buf = set_buffer( tmp );
- insert("(load \"");
- insert( name );
- move_abs( NULL, 1 );
- translate("\\\\", "/", 1 );
- end_of_line();
- insert("\")\n");
- write_buffer();
- set_buffer( buf );
- delete_buffer( tmp );
- exit();
- }
-
- /************************************************************************
- * List all procedures in a dialog *
- ************************************************************************/
- int s_goto_line, s_goto_col;
-
- int s_menu_action( int event, ... )
- {
- if( event == DIALOG_PICK_MENU )
- {
- string text;
-
- get_parm( 2, text );
- text = substr( text, index(text,";")+2 );
- s_goto_line = atoi( substr(text,1,index(text," ")-1) );
- text = substr( text, index(text," ")+1 );
- s_goto_col = atoi( text );
- _dialog_esc();
- }
- return TRUE;
- }
-
- void s_list_proc()
- {
- int menu = create_buffer("Defines", NULL, 1 ), count, width = MINMENU;
-
- save_position();
- s_goto_line = 0;
- top_of_buffer();
- for(;;)
- {
- string buf;
- int line, col, oldbuf;
-
- if( !search_fwd("(define", NULL, 0 ) )
- {
- if( count )
- break;
- else {
- error("No define found.");
- delete_buffer(menu);
- return;
- }
- } else count++;
-
- next_char( search_fwd("(define[ \t\n]@[~ \t\n]", NULL, 0 ) - 2 );
- if( read(1) == "(")
- buf = read( search_fwd("(*)")-1 );
- else buf = read( search_fwd("*[) \t\n]")-2 );
- inq_position( line, col );
-
- oldbuf = set_buffer( menu );
- if( strlen(buf) > width )
- width = strlen(buf);
- if( width > MAXMENU )
- {
- width = MAXMENU;
- buf = substr( buf, 1, MAXMENU );
- }
- insert( buf );
- sprintf( buf, " ; %d %d\n", line, col );
- insert( buf );
- set_buffer( oldbuf );
- message("%d defines...", count );
- }
-
- count = set_buffer( menu );
- prev_char();
- delete_char();
- top_of_buffer();
- while( search_fwd(";") > 0 )
- {
- insert("\n");
- move_rel( -1, width+1 );
- delete_char();
- end_of_line();
- }
- set_buffer( count );
- restore_position();
-
- _process_menu( 32, 3, 32, 3, "", "", NULL, menu, "s_menu_action", TRUE );
- delete_buffer( menu );
- if( s_goto_line )
- {
- int newtop;
- inq_window_size( newtop, NULL );
- newtop = s_goto_line - newtop/4;
- move_abs( s_goto_line, s_goto_col );
- set_top_left( newtop > 0 ? newtop : 1 );
- }
- }
-
- /************************************************************************
- * Give some help on the package *
- ************************************************************************/
- int s_help_action(...)
- {
- return TRUE;
- }
-
- void s_help()
- {
- _process_menu( 2, 21, 76, 2, "PCS package", "", "scheme.mnu", NULL, "s_help_action", TRUE );
- }
-
- /************************************************************************
- * Goto the next / previous word *
- ************************************************************************/
- void s_prev()
- {
- prev_char(2);
- search_back("{{[ \t,.'`()]|%}\\c[~ \t\n,.'`()]}|{[~()]\\c[()]}");
- }
-
- void s_next()
- {
- if( search_fwd("{{[ \t,.'`()]|%}\\c[~ \t\n,.'`()]}|{[~()]\\c[()]}") <= 0 )
- end_of_line();
- }
-
- /************************************************************************
- * Toggle mode *
- ************************************************************************/
- void s_toggle()
- {
- s_mode = !s_mode;
- message("PCS Package is %s", s_mode ? "on" : "off");
- }